Skip to content

Extract rollout-redis as a separate adapter gem - #181

Closed
michal-granec wants to merge 5 commits into
v3-feature-statefrom
v3-redis-backend
Closed

Extract rollout-redis as a separate adapter gem#181
michal-granec wants to merge 5 commits into
v3-feature-statefrom
v3-redis-backend

Conversation

@michal-granec

Copy link
Copy Markdown
Contributor

Stacked on #180.

Summary

  • Extract Redis persistence and history into rollout-redis (Rollout::Redis::Backend + Rollout::Redis::Codec).
  • Core Rollout now takes backend: and no longer depends on redis.
  • Split tests: core specs run without Redis; adapter specs live in rollout-redis/spec.

This is the second Rollout 3 slice. It does not add Active Record, change hashing, or raise the Ruby requirement.

Test plan

  • Core CI job green without a Redis service
  • Redis adapter CI job green on the existing Ruby 2.4–3.3 matrix
  • Existing Redis payloads still load without rewriting unread keys
  • Rollout.new(backend: Rollout::Redis::Backend.new(redis)) activates, deactivates, and evaluates as before
  • History still truncates per history_length; delete removes feature history; clear! keeps it

Checks: core 20 examples passed, Redis adapter 103 examples passed, rebased onto v3-feature-state.

Move Redis persistence and history into Rollout::Redis::Backend.
Core Rollout takes a backend and no longer depends on redis.
setup-ruby should install rollout-redis/Gemfile from that directory so
BUNDLE_GEMFILE is unnecessary and bundle exec rspec finds the gems.
Bump core to 3.0.0, require a compatible core range in the adapter, and
keep logging/observer snapshot eligibility consistent through a mutation.
Read only the requested history entries, decode Redis events in the
adapter, and give the backend a clear_features hook so clear! can remove
the empty registry without changing logging-disabled delete behavior.
The shared examples live in the repository spec/support directory, two
levels above the adapter specs.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved CI/release packaging, Bundler compatibility, and backend-isolation issues block approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This pull request extracts Redis persistence into the standalone rollout-redis adapter and makes core Rollout backend-neutral.

Changes:

  • Adds backend contracts and backend-based core persistence.
  • Introduces the Redis adapter, codec, and adapter-specific tests.
  • Updates packaging, documentation, Rake tasks, and CI workflows.
File summaries
File Summary
spec/support/backend_contract.rb Defines shared backend contract examples.
spec/spec_helper.rb Provides the in-memory test backend; fetched states need deep cloning for isolation.
spec/rollout/logging_spec.rb Tests backend-neutral logging.
spec/rollout/feature_state_spec.rb Tests backend-neutral feature state behavior.
spec/rollout/feature_spec.rb Tests feature behavior.
spec/rollout_spec.rb Tests core Rollout behavior.
rollout.gemspec Removes the Redis dependency and extracted files.
rollout-redis/spec/spec_helper.rb Configures adapter test setup.
rollout-redis/spec/rollout_integration_spec.rb Tests Redis integration behavior.
rollout-redis/spec/history_spec.rb Tests Redis history behavior.
rollout-redis/spec/codec_spec.rb Tests Redis codec behavior.
rollout-redis/spec/backend_contract_spec.rb Applies the backend contract to Redis.
rollout-redis/rollout-redis.gemspec Defines the adapter gem.
rollout-redis/lib/rollout/redis/codec.rb Implements Redis encoding and decoding.
rollout-redis/lib/rollout/redis/backend.rb Implements Redis persistence and history.
rollout-redis/lib/rollout/redis.rb Provides the adapter entry point.
rollout-redis/Gemfile Defines adapter dependencies.
rollout-redis/.rspec Configures adapter RSpec.
README.md Documents adapter installation and usage.
Rakefile Adds core and adapter test tasks; older Bundler compatibility remains unresolved.
lib/rollout/version.rb Sets version 3.0.0.
lib/rollout/redis_codec.rb Removes the core Redis codec.
lib/rollout/logging.rb Delegates history storage to backends.
lib/rollout.rb Uses backend-based persistence.
.github/workflows/test.yml Splits core and Redis CI; adapter setup needs its own Gemfile.
.github/workflows/release.yml Tests the adapter, but the release still excludes publishing it and needs adapter bundle setup.
Review details

Suppressed comments (4)

.github/workflows/release.yml:33

  • This setup step has the same ineffective working-directory input, so the release job does not install the adapter bundle before running bundle exec rspec from rollout-redis; with Redis removed from the root bundle, the adapter tests can fail immediately on require 'redis'. Configure BUNDLE_GEMFILE for the setup step or run an explicit adapter bundle install.
          working-directory: rollout-redis

.github/workflows/test.yml:59

  • working-directory is being passed as an input to ruby/setup-ruby, so it does not change the directory in which bundler-cache runs. The action will install the root Gemfile (which no longer includes redis), while the following command resolves rollout-redis/Gemfile and can fail at require 'redis'; set BUNDLE_GEMFILE for this setup step or add an explicit adapter bundle install.
          working-directory: rollout-redis

Rakefile:16

  • The gemspec still permits Bundler >= 1.17, but with_unbundled_env is not available in Bundler 1.x. The documented bundle exec rake spec:redis command therefore raises before running tests on an allowed Bundler version; use a with_clean_env fallback for older Bundlers.
      Bundler.with_unbundled_env do
        sh({ "BUNDLE_GEMFILE" => gemfile }, "bundle exec rspec")

spec/spec_helper.rb:17

  • This test double stores and returns the same FeatureState instance, so mutating a nested value on a fetched state also mutates the backend. That violates the isolation required by the shared backend contract in spec/support/backend_contract.rb; return a deep clone from fetch_feature so core tests exercise the same contract as the Redis adapter.
    @features[name.to_s] || Rollout::FeatureState.new(name: name, percentage: 0)
  • Files reviewed: 26/26 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +30 to +37
- name: Setup Redis adapter gems
uses: ruby/setup-ruby@v1
with:
working-directory: rollout-redis
bundler-cache: true
- name: Run Redis adapter tests
working-directory: rollout-redis
run: bundle exec rspec
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants